package com.che.libcommon.api.page;


import android.support.annotation.NonNull;
import android.util.Log;
import com.che.libcommon.api.page.PageList.PageInfo;
import com.che.libcommon.utils.optional.Optional;
import io.reactivex.Single;
import io.reactivex.SingleObserver;
import io.reactivex.functions.IntFunction;
import io.reactivex.observers.ResourceSingleObserver;
import java.util.List;

class PaginationWrapper<T> {

  PageInfo pageInfo;

  private IntFunction<Single<Optional<PageList<T>>>> apiFunction;

  private ResourceSingleObserver<Optional<PageList<T>>> subscriber;

  boolean isRunning = false;

  int loadingPage=0;

  public static <T> PaginationWrapper<T> create(IntFunction<Single<Optional<PageList<T>>>> api){
    return new PaginationWrapper<T>(api);
  }


  private PaginationWrapper(IntFunction<Single<Optional<PageList<T>>>> api) {
    apiFunction = api;
  }

  /**
   * 重置
   * @return
   */
  public PaginationWrapper<T> reset(){
    if(subscriber != null && !subscriber.isDisposed()){
      subscriber.dispose();
    }
    subscriber = null;
    pageInfo = null;

    return this;
  }

  public int getCurrPage(){
    if(pageInfo == null){
      return 0;
    }
    return pageInfo.currentPage;
  }

  /**
   * 获取下一页页码
   * @return
   */
  public int getNextPage(){
    return getCurrPage()+1;
  }

  public boolean isFirst(){
    return pageInfo == null || pageInfo.currentPage == 1;
  }

  public boolean isEnd(){

    if(pageInfo != null){
      return pageInfo.currentPage >= pageInfo.pageNum;
    }

    return false;
  }


  /**
   * 加载下一页
   * @param observer
   */
  public void next(@NonNull SingleObserver<Optional<List<T>>> observer){
    try {
      if(!isRunning && !isEnd()){
        isRunning = true;
        doNext(observer);
      }
    } catch (Exception e) {
      e.printStackTrace();
      isRunning = false;
    }
  }

  private void doNext(@NonNull final SingleObserver<Optional<List<T>>> observer) throws Exception {

    loadingPage = getNextPage();
    Single<Optional<PageList<T>>> apply = apiFunction.apply(loadingPage);

    if(subscriber != null && !subscriber.isDisposed()){
      subscriber.dispose();
    }

    subscriber = new ResourceSingleObserver<Optional<PageList<T>>>() {

      @Override
      public void onSuccess(Optional<PageList<T>> pageListOptional) {

        isRunning = false;

        PageList<T> tPageList = pageListOptional.orNull();

        if (tPageList != null) {
          pageInfo = tPageList.pageInfo;

          observer.onSuccess(Optional.ofNullable(tPageList.list));

        }

      }

      @Override
      public void onError(Throwable e) {

        isRunning = false;

        observer.onError(e);
      }
    };
    apply.subscribe(subscriber);

  }

}
